#ifndef TABOOLIST_H_
#define TABOOLIST_H_

#include "tabooExpire.h"

/**Una matrice di singoli Taboo. */
typedef TabooExpire** TabooMat;

/* Singola struttura TabooList associata a un veicolo. */
typedef struct TabooList {
	/** Matrice analoga a quella di adiacenza del grafo*/
	TabooMat tm;
	/** indica una cella di memoria in cui e' contenuto il numero totale dei nodi del grafo */
	int* N;
} TabooList;

/* Puntatore di servizio. */
typedef TabooList* PtabooList;

//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~COSTRUTTORI/DISTRUTTORI~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
/**costruisce una nuova taboolist e inizializza tutti i taboo a una certa data di espirazione.
 * Generalmente quindi il parametro now sarà pari a 0 cioè alla prima iterazione di STM, ma in modifiche dell'algoritmo
 * si potrebbe volerlo impostare pari a qualcos'altro.
 * @param _N indica un puntatore ad una cella di memoria in cui risiede il numero dei nodi del grafo
 * @return
 */
PtabooList initTabooList(int* _N, TabooExpire now);

/**dealloca in modo corretto la taboolist passata come parametro
 *
 * \pre
 *  \li ptl non NULL
 *
 * @param taboolist la taboolist da deallocare dalla memoria
 */
void freeTabooList(PtabooList ptl);


//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~OPERAZIONI~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~


/**resetta ogni valore contenuto in questa taboolist al valore passato come parametro
 *
 * \pre
 *  \li ptl non NULL
 * \post
 *  \li all'interno di tm sono specificati solo valori uguali a resetvalue
 *
 * @param ptl la taboolist da modificare
 * @param resetvalue il valore da sostituire in ogni cella specificata da tm
 */
void resetTabooList(PtabooList ptl,TabooExpire resetvalue);

/**imposta il valore di un taboo all'interno della TL. Se il particolare arco possedeva gia' un taboo, il piu' vecchio viene scartato.
 *
 * 	\pre
 * 	 \li ptl non NULL
 * 	 \li edge non NULL
 * 	 \li edge ha i<j
 *
 * 	\post
 * 	 all'interno della taboolist alle coordinate di edge esiste la somma tra tenure e now
 *
 * @param taboolist indica la lista che deve accogliere il nuovo taboo
 * @param edge indica l'arco coinvolto nel taboo
 * @param tenure indica la tenure a cui l'edge e' sottoposto
 * @param timestamp indica l'iterazione dell'algoritmo in cui questo taboo e' starto creato.
 */
void setTaboo(PtabooList ptl, PedgeID edge, int tenure, TabooExpire now);

/**controlla se l'edge passato sia taboo o no.
 * TRUE se taboo.timestamp+taboo.tenure<=currentTimeStamp, FALSE altrimenti.
 *
 * \pre
 *  \li ptl non NULL
 *  \li edge non NULL
 *  \li edge deve avere i<j
 *
 * @param taboolist indica la taboo list in cui controllare l'arco
 * @param edge indica l'arco da controllare
 * @param timestamp indica l'iterazione in cui si trova l'algoritmo
 * @return TRUE l'edge e' ancora taboo, FALSE altrimenti
 */
bool isEdgeTaboo(PtabooList p_tabooList, PedgeID p_edge, TabooExpire now);

int getEdgeTenure(PtabooList p_tabooList, PedgeID p_edge, TabooExpire now);

//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~STAMPA~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
/** Stampa la matrice associata a una tabooList, dove ogni elemento m[i][j] rappresenta
 *	la data di espirazione dell'arco m[i][j].
 *
 * \pre
 *  \li f aperto in scrittura
 *  \li ptl non NULL
 *
 * \post
 *  \li f viene alterato scrivendo sopra caratteri
 *
 * @param f il file su cui scrivere la rappresentazione testuale
 * @param taboolist la taboo list da stampare
 */
void printTabooList(FILE* f, PtabooList ptl);

void printTabooListExpirations(FILE* f, PtabooList ptl, TabooExpire now, int k);

/** DEPRECATA. stampa una comparazione tra tutti i taboo presenti nella taboo list e il clock passato come parametro,
 * riportando anche TRUE qualora il taboo sia ancora valido, FALSE altrimenti
 *
 * @param f il file su cui vera' stampato il taboo
 * @param taboolist la lista da cui reperire taboos
 * @param clock il clock dell'algoritmo
 */
void printComparationTabooList(FILE* f, PtabooList ptl, TabooExpire now);

/** Stampa la matrice associata a una tabooList, dove ogni elemento m[i][j] rappresenta
 *	il numero di iterazioni ancora vietate dell'arco m[i][j].
 *
 * @param f il file su cui scrivere la rappresentazione della taboo List
 * @param ptl un riferimento alla taboo List da stmapare
 * @param now il numero di iterazioni globali a cui l'algoritmo e' arrivato in questo momento
 */
void printTabooListTenures(FILE* f, PtabooList ptl, TabooExpire now, int k);

/**
 * Stampa la taboo list come un insieme di archi vietati. Formato più vicino a quello propriamente "a lista"
 *
 * \pre
 *  \li f aperto in scrittura (per esempio "w" o in "a")
 *  \li ptl non NULL
 *  \li k compreso tra [0;K]
 * \post
 *  \li il file viene alterato scrivendoci sopra una visione umana della tabooList
 *
 * @param f il file su cui scrivere la rappresentazione della taboo List
 * @param ptl un riferimento alla taboo List da stmapare
 * @param now il numero di iterazioni globali a cui l'algoritmo e' arrivato in questo momento
 */
void printTabooListAsSet(FILE* f, PtabooList ptl, TabooExpire now, int k);

#endif /* TABOOLIST_H_ */
